package com.imdroid.carac.activities;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Set;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.telephony.SmsManager;
import android.util.Log;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Toast;

import com.imdroid.carac.IMDroid;
import com.imdroid.carac.R;
import com.imdroid.carac.net.HttpHelper;
import com.imdroid.carac.process.ProcessFactory;
import com.imdroid.carac.process.UserProcess;

public class SecurityHomeActivity extends BaseActivity implements
		SensorEventListener {
	/**
	 * The tag of this activity
	 */
	private static String TAG = "SecurityHomeActivity";
	/**
	 * The active instance
	 */
	public static SecurityHomeActivity instance = null;
	/**
	 * The sensor manager
	 */
	private SensorManager sensorManager;
	/**
	 * The sensor of accelerometer
	 */
	private Sensor accelerometer;
	/**
	 * if the activity is monitoring
	 */
	private boolean monitor = true;
	/**
	 * The last value of accelerometer
	 */
	private float lastValue = 0;
	/**
	 * The time of last warning
	 */
	private long lastWarning = 0;
	/**
	 * the duration of next warning
	 */
	private static long Next_Warning_Time = 3 * 60 * 1000;
	/**
	 * The battery change receiver
	 */
	private BroadcastReceiver batteryChangeReceiver = new MyBatteryChangeReceiver();
	/**
	 * If need to exit automatically if the power is plug again.
	 */
	private boolean autoBack = false;
	/**
	 * The maxmium tolerance
	 */
	private float tolerance = (float) 1.5;
	public SurfaceView surfaceView = null;
	public final static int MESSAGE_TAKE_PICTURE = 0x120;
	public long lastTakingTime = 0;
	/**
	 * Check if this activity is running
	 */
	public boolean running;

	// private WakeLock wl;

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onCreate(android.os.Bundle)
	 */
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// 初始化界面控件
		setContentView(R.layout.security_home);
		surfaceView = (SurfaceView) findViewById(R.id.security_suface_view);
		instance = this;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onResume()
	 */
	@SuppressWarnings("deprecation")
	protected void onResume() {
		super.onResume();
		autoBack = false;
		tolerance = IMDroid.getAntiTheftTolerance();

		this.registerReceiver(batteryChangeReceiver, new IntentFilter(
				Intent.ACTION_BATTERY_CHANGED));
		// wl = ((PowerManager) getSystemService(Activity.POWER_SERVICE))
		// .newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP
		// | PowerManager.SCREEN_DIM_WAKE_LOCK, "");
		// wl.acquire();
		// 如果短信要求拍照
		if (this.getIntent() != null && this.getIntent().getExtras() != null) {
			String action = this.getIntent().getExtras().getString("action");
			if ("TakingPicture".equals(action)) {
				long now = (new Date()).getTime();
				if (now - lastTakingTime >= 5 * 1000) {
					this.getIntent().getExtras().putString("action", null);
					String feedBackNumber = this.getIntent().getExtras()
							.getString("feedBackNumber");
					monitor = false;
					Message message = new Message();
					message.what = SecurityHomeActivity.MESSAGE_TAKE_PICTURE;
					message.obj = feedBackNumber;
					messageHandler
							.obtainMessage(
									message.what = SecurityHomeActivity.MESSAGE_TAKE_PICTURE)
							.sendToTarget();
					lastTakingTime = now;
				}

			}
		} else {
			monitor = true;
		}
		// 注册感應器
		sensorManager = (SensorManager) this.getSystemService(SENSOR_SERVICE);
		accelerometer = sensorManager
				.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
		sensorManager.registerListener(this, accelerometer,
				SensorManager.SENSOR_ACCELEROMETER);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onStart()
	 */
	protected void onStart() {
		running = true;

		super.onStart();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onStop()
	 */
	@Override
	protected void onStop() {
		super.onStop();
		running = false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onPause()
	 */
	protected void onPause() {
		super.onPause();
		// if (wl != null)
		// wl.release();
		sensorManager.unregisterListener(this);
		this.unregisterReceiver(batteryChangeReceiver);

	}

	/**
	 * Get the handler object;
	 * 
	 * @return
	 */
	public Handler getHandler() {
		return messageHandler;
	}

	/**
	 * Back to the main screen
	 * 
	 * @param view
	 *            the of button
	 */
	public void exit(View view) {
		this.finish();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.imdroid.carac.activities.BaseActivity#processedMessage(android.os
	 * .Message)
	 */
	public void processedMessage(Message msg) throws Exception {
		switch (msg.what) {
		case MESSAGE_TAKE_PICTURE:
			String feedBackNumber = (msg.obj != null) ? (String) msg.obj
					: IMDroid.getUser().getMobile_phone();
			// 拍照
			(new TakingPictureTask()).execute(feedBackNumber, "0");

			break;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * android.hardware.SensorEventListener#onAccuracyChanged(android.hardware
	 * .Sensor, int)
	 */
	public void onAccuracyChanged(Sensor sensor, int accuracy) {

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * android.hardware.SensorEventListener#onSensorChanged(android.hardware
	 * .SensorEvent)
	 */
	public void onSensorChanged(SensorEvent event) {
		int sensorType = event.sensor.getType();
		float[] values = event.values;

		if (sensorType == Sensor.TYPE_ACCELEROMETER && monitor) {
			float motion = (values[0] > values[1] ? values[0] : values[1]);
			motion = (motion > values[2] ? motion : values[2]);

			float shock = Math.abs((float) (motion - 9.8));
			// Log.d(TAG, "Security - " + shock + "|" + tolerance);

			if (monitor && lastValue > 0 && (shock > tolerance)) {
				// 如果距上次报警时间小于30秒，则忽略
				long now = (new Date()).getTime();
				if (now - lastWarning <= Next_Warning_Time) {
					// Log.d(TAG, "Duration not engouh, ingore...");
					return;
				}
				// 报警期间，设置成不在监控
				monitor = false;
				// 进入警告模式(会判断是否车主)
				warnning();
				// 更新上次报警时间
				lastWarning = (new Date()).getTime();
			}
			lastValue = motion;
		}

	}

	/**
	 * Sensor the vibrate
	 */
	private void warnning() {
		boolean check = isUserNearBy();

		if (check) {
			if (SecurityHomeActivity.instance != null) {
				Message message = new Message();
				message.what = SecurityHomeActivity.MESSAGE_EXIT;
				try {
					SecurityHomeActivity.instance.processedMessage(message);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		} else {
			try {
				alert();
			} catch (Exception ex) {
				ex.printStackTrace();
			} finally {
				// 最后设置重新监控
				monitor = true;
			}
		}
	}

	/**
	 * Send the warning SMS to the users
	 * 
	 * @throws Exception
	 */
	@SuppressLint("SimpleDateFormat")
	private void sendSMS() throws Exception {
		// 发送短信
		String mobileNumber = IMDroid.getUser().getMobile_phone();
		if (mobileNumber != null && mobileNumber.length() > 0) {
			SharedPreferences sp = PreferenceManager
					.getDefaultSharedPreferences(IMDroid.getContext());
			Resources resources = IMDroid.getContext().getResources();

			boolean allowPic = sp.getBoolean(
					resources.getString(R.string.KEY_SEC_PIC), true);

			String text = IMDroid.getContext().getString(
					allowPic ? R.string.security_alert_2
							: R.string.security_alert_1);

			text = text.replace("#1#", IMDroid.getUser().getBoard_plate());
			SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
			text = text.replace("#2#", sdf.format(new Date()));

			 Log.e(TAG, "sms:" + mobileNumber + " " + text);
			 UserProcess userProcess = (UserProcess) ProcessFactory
			 .getProcess(UserProcess.class);
			 userProcess.sendSMS(mobileNumber, text);
			// SmsManager smsManager = SmsManager.getDefault();
			// PendingIntent sentIntent = PendingIntent.getBroadcast(
			// IMDroid.getContext(), 0, new Intent(), 0);
			// smsManager.sendTextMessage(mobileNumber, null, text, sentIntent,
			// null);
		}
	}

	/**
	 * Send the alert to the users
	 */
	private void alert() throws Exception {
		// 从share preference 中捉去是否需要警告短信或者拍照
		SharedPreferences sp = PreferenceManager
				.getDefaultSharedPreferences(IMDroid.getContext());
		Resources resources = IMDroid.getContext().getResources();
		boolean allowSMS = sp.getBoolean(
				resources.getString(R.string.KEY_SEC_SMS), true);
		boolean allowPic = sp.getBoolean(
				resources.getString(R.string.KEY_SEC_PIC), true);

		// 发送警告短信
		if (allowSMS)
			sendSMS();

		Log.e(TAG, "Take picture after 20sec..");
		// Thread.sleep(20 * 1000);
		// 拍照
		if (allowPic)
			(new TakingPictureTask()).execute(IMDroid.getUser()
					.getMobile_phone(), "1");
		// takePhoto(1);
	}

	/*
	 * Check if the user near by
	 * 
	 * @return if the user near by.
	 */
	private boolean isUserNearBy() {
		// 得到所有跟车机配对的蓝牙设配
		BluetoothAdapter mBluetoothAdapter = BluetoothAdapter
				.getDefaultAdapter();
		mBluetoothAdapter.cancelDiscovery();
		Set<BluetoothDevice> pairedDevices = mBluetoothAdapter
				.getBondedDevices();

		Log.d(this.getClass().getSimpleName(), "Paired Devices size:"
				+ pairedDevices.size());

		if (pairedDevices.size() > 0) {
			// Loop through paired devices
			for (BluetoothDevice device : pairedDevices) {
				Log.d(this.getClass().getSimpleName(), "Paired Devices:"
						+ device.getName() + "||" + device.getAddress() + "||"
						+ device.getBondState());
				// 尝试连接客户的蓝牙
				try {
					Method method = device.getClass().getMethod(
							"createRfcommSocket", new Class[] { int.class });
					BluetoothSocket btSocket = (BluetoothSocket) method.invoke(
							device, 1);
					btSocket.connect();
					return true;
				} catch (Exception ex) {
					Log.d(this.getClass().getSimpleName(),
							"Connecting Devices:" + device.getName() + " - "
									+ ex.getMessage());
					if (ex.getMessage().equalsIgnoreCase("Connection refused"))
						return true;
				}
			}
		}
		return false;
	}

	/**
	 * The async task to take the picture and upload
	 * 
	 */
	public class TakingPictureTask extends AsyncTask<String, Integer, Boolean> {
		boolean _monitor;
		/**
		 * The data and time
		 */
		String dateTime = (new Date()).getTime() + "";
		/**
		 * The feedback number of SMS
		 */
		String feedBackNumber = null;
		/**
		 * 1- 震动拍照， 0或空-遥控拍照
		 */
		// String pictureType = null;
		/**
		 * The file from front camera and back camera
		 */
		String fileName1 = null;
		String fileName2 = null;

		// private UserProcess process = (UserProcess) ProcessFactory
		// .getProcess(UserProcess.class);

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#doInBackground(Params[])
		 */
		protected Boolean doInBackground(String... params) {
			// 先定义文件名字
			fileName1 = (new Date()).getTime() + "_1.jpg";
			fileName2 = (new Date()).getTime() + "_2.jpg";

			// 先记住原来是否有检测震动的标记，暂时屏蔽检测
			_monitor = monitor;
			monitor = false;
			this.feedBackNumber = params[0];

			// 前摄像头拍摄
			takePhoto(0);
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			// 后摄像头拍摄
			takePhoto(1);
			// 上传文件
			Log.d(TAG, "Upload.............");
			(new PictureUploadThread(fileName1, fileName2, feedBackNumber))
					.start();
			return true;

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
		 */
		protected void onPostExecute(Boolean result) {
			Toast.makeText(SecurityHomeActivity.this,
					"Picture is taken-" + dateTime, Toast.LENGTH_LONG).show();

			Activity activity = SecurityHomeActivity.this;
			String action = activity.getIntent().getExtras()
					.getString("action");

			// Log.d(TAG, "ACTION-----" + action);
			// 如果进来的窗口不是原来的窗口
			if ("TakingPicture".equals(action)) {
				SecurityHomeActivity.this.finish();
			}

			monitor = _monitor;

		}

		/**
		 * Take the photo
		 */
		private void takePhoto(final int cameraId) {
			Camera camera = null;
			try {
				camera = Camera.open(cameraId);
			} catch (Exception ex) {
				try {
					Thread.sleep(5 * 1000);
					camera = Camera.open(cameraId);
				} catch (Exception e) {
					return;
				}
			}

			try {
				Parameters parameters = camera.getParameters();
				parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
				parameters.setSceneMode(Parameters.SCENE_MODE_AUTO);
				// parameters.setAntibanding(Parameters.ANTIBANDING_60HZ);
				// parameters.setWhiteBalance(Parameters.WHITE_BALANCE_DAYLIGHT);
				// int value = (parameters.getMaxExposureCompensation());
				// parameters.setExposureCompensation(value);
				camera.setParameters(parameters);
				camera.setPreviewDisplay(surfaceView.getHolder());
				camera.startPreview();
				camera.takePicture(null, null, new JpegPictureCallback(
						cameraId == 0 ? fileName1 : fileName2));
				Log.d(TAG, "Picture taken--end--");
				/*
				 * camera.autoFocus(new AutoFocusCallback() {
				 * 
				 * @Override public void onAutoFocus(boolean success, Camera
				 * camera) { // if (success) { camera.takePicture(null, null,
				 * new JpegPictureCallback( cameraId == 0 ? fileName1 :
				 * fileName2)); Log.d(TAG, "Picture taken--end--"); // } } });
				 */
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		/**
		 * The inner class for saving the jpeg file which the camera took
		 * 
		 */
		private final class JpegPictureCallback implements PictureCallback {
			/**
			 * The file name of the picture saving
			 */
			String fileName = null;

			/**
			 * 
			 */
			private JpegPictureCallback(String fileName) {
				super();
				this.fileName = fileName;
				Log.d(TAG, "Picture taken--ccc--" + fileName);
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see
			 * android.hardware.Camera.PictureCallback#onPictureTaken(byte[],
			 * android.hardware.Camera)
			 */
			public void onPictureTaken(final byte[] jpegData,
					android.hardware.Camera camera) {
				try {
					if (jpegData != null) {
						Bitmap bitmap = BitmapFactory.decodeByteArray(jpegData,
								0, jpegData.length);
						File captureFile = new File(IMDroid.SECURITY_FOLDER
								+ fileName);

						BufferedOutputStream bos = new BufferedOutputStream(
								new FileOutputStream(captureFile));
						bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
						bos.flush();
						bos.close();

						camera.stopPreview();
						camera.release();
						Log.d(TAG, "Picture taken--dddd--" + jpegData.length);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * The thread of the upload the pictures
	 * 
	 */
	private class PictureUploadThread extends Thread {
		private String picture1;
		private String picture2;
		private String phoneNumber;

		private UserProcess process = (UserProcess) ProcessFactory
				.getProcess(UserProcess.class);

		/**
		 * The constructor
		 */
		public PictureUploadThread(String picture1, String picture2,
				String phoneNumber) {
			this.picture1 = picture1;
			this.picture2 = picture2;
			this.phoneNumber = phoneNumber;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Thread#run()
		 */
		public void run() {
			while (true) {
				// 上传图片
				try {
					File file = new File(IMDroid.SECURITY_FOLDER + picture1);
					if (file.exists())
						process.uploadPitcure(IMDroid.SECURITY_FOLDER, picture1);
					file = new File(IMDroid.SECURITY_FOLDER + picture2);
					if (file.exists())
						process.uploadPitcure(IMDroid.SECURITY_FOLDER, picture2);

					String shortURL1 = HttpHelper
							.getShortenURL(HttpHelper.webAddress
									+ "resource/p/"
									+ IMDroid.getUser().getUser_id() + "/"
									+ picture1);

					String shortURL2 = HttpHelper
							.getShortenURL(HttpHelper.webAddress
									+ "resource/p/"
									+ IMDroid.getUser().getUser_id() + "/"
									+ picture2);
					// 格式化短信内容
					Context context = SecurityHomeActivity.this;
					String content = context
							.getString(R.string.security_pic_send);
					content = content.replace("#1#", shortURL1).replace("#2#",
							shortURL2);

					// 短信发送
					 process.sendSMS(phoneNumber.trim(), content + "\n");

//					SmsManager smsManager = SmsManager.getDefault();
//					PendingIntent sentIntent = PendingIntent.getBroadcast(
//							IMDroid.getContext(), 0, new Intent(), 0);
//
//					// Log.d(TAG, "sms:" + text);
//					smsManager.sendTextMessage(phoneNumber.trim(), null,
//							content + "\n", sentIntent, null);
					Log.d(TAG, "SMS----Send...");
					break;
				} catch (Exception e) {
					e.printStackTrace();
				}
				// 演示30秒再发
				try {
					Thread.sleep(30 * 1000);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

		}
	}

	/**
	 * The class of battery change recevier
	 * 
	 */
	private class MyBatteryChangeReceiver extends BroadcastReceiver {
		private static final int BATTERY_PLUGGED_UNPLUG = 0;

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * android.content.BroadcastReceiver#onReceive(android.content.Context,
		 * android.content.Intent)
		 */
		public void onReceive(Context context, Intent intent) {
			int plugged = intent.getIntExtra("plugged", BATTERY_PLUGGED_UNPLUG);
			// Toast.makeText(IMDroid.getContext(), "--" + autoBack,
			// Toast.LENGTH_SHORT).show();

			// 重新街电时
			if (plugged != BATTERY_PLUGGED_UNPLUG && autoBack) {
				Log.d(TAG, "The power is plug");
				SecurityHomeActivity.this.finish();
			}
			autoBack = true;
		}
	}
}
